﻿using AutoMapper;
using Enferno.Public.Web.Mappers.Resolvers;
using Enferno.Public.Web.Models;
using Enferno.StormApiClient.Products;

namespace Enferno.Public.Web.Mappers.ProductProfiles
{
    public class ProductToProductModelProfile :
        ProductToCustomProductModelProfile<ProductModel>
    {
        public override string ProfileName
        {
            get { return GetType().Name; }
        }
    }

    public class ProductToCustomProductModelProfile<TProductModel> :
        ProductToCustomProductWithCustomVariantModelProfile<TProductModel, VariantModel>
        where TProductModel: ProductWithCustomVariantModel<VariantModel>
    {
        
    }

    public class ProductToCustomProductWithCustomVariantModelProfile<TProductModel, TVariantModel> : ProductToProductBaseModelProfile
            <TProductModel, TVariantModel, OnHandStatusModel, PriceModel, ProductFileModel, ProductManufacturerModel,
                ProductListCustomVariantModel<TVariantModel, ProductItemCustomVariantModel<TVariantModel>>, ProductItemCustomVariantModel<TVariantModel>, FilterModel, 
                ParametricModel, ParametricValueModel>
        where TProductModel: ProductWithCustomVariantModel<TVariantModel>
        where TVariantModel: VariantBaseModel<OnHandStatusModel, PriceModel, ProductFileModel, ParametricModel, ParametricValueModel> {}

    public class ProductToProductBaseModelProfile<
        TProductModel, 
        TVariantModel, 
        TOnHandStatusModel, 
        TPriceModel, 
        TProductFileModel, 
        TProductManufacturerModel, 
        TProductListModel, 
        TProductItemModel, 
        TFilterModel,
        TParametricModel, 
        TParametricValueModel>  : Profile
        where TProductModel: ProductBaseModel<TVariantModel, TProductManufacturerModel, TProductListModel, TProductItemModel, TFilterModel, TProductFileModel, TPriceModel, TOnHandStatusModel, TParametricModel, TParametricValueModel>
        where TVariantModel: VariantBaseModel<TOnHandStatusModel, TPriceModel, TProductFileModel, TParametricModel, TParametricValueModel>
        where TOnHandStatusModel: OnHandStatusModel, new()
        where TPriceModel: PriceModel, new()
        where TProductFileModel: ProductFileModel, new()
        where TParametricModel: ParametricBaseModel<TParametricValueModel>
        where TParametricValueModel: ParametricValueModel
        where TProductManufacturerModel: ProductManufacturerModel
        where TProductListModel: ProductListBaseModel<TProductItemModel, TFilterModel, TVariantModel, TProductFileModel, TProductManufacturerModel, TPriceModel, TOnHandStatusModel, TParametricModel, TParametricValueModel>
        where TProductItemModel: ProductItemBaseModel<TVariantModel, TProductFileModel, TProductManufacturerModel, TPriceModel, TOnHandStatusModel, TParametricModel, TParametricValueModel>
        where TFilterModel: FilterModel
    {
        protected IMappingExpression<Product, TProductModel> Mapping { get; set; } 

        protected override void Configure()
        {
            var mapping = Mapping ?? Mapper.CreateMap<Product, TProductModel>();

            mapping
                .ForMember(
                    to => to.Category,
                    opts =>
                        opts.ResolveUsing(
                            product =>
                            {
                                var model = new ProductCategoryModel {Name = product.CategoryName};
                                if (product.CategoryId.HasValue)
                                    model.Id = product.CategoryId.Value;
                                return model;
                            }))
                .ForMember(to => to.Flags, opts => opts.ResolveUsing<ProductFlagsResolver>())
                .ForMember(to => to.Files, opts => opts.ResolveUsing<ProductFilesResolver<TProductFileModel>>())
                .ForMember(to => to.OnHandStatus, opts => opts.ResolveUsing<ProductOnHandStatusResolver<TOnHandStatusModel>>())
                .ForMember(to=> to.Price, opts=> opts.ResolveUsing<ProductPriceResolver<TPriceModel>>())
                .ForMember(to => to.UnitOfMeasurement, opts => opts.MapFrom(from => from.Uom))
                .ForMember(to => to.Families, opts => opts.Ignore()) //mapped in the builder
                .ForMember(to => to.Products, opts => opts.Ignore()) //mapped in the builder
                .ForMember(to => to.Variants, opts => opts.Ignore()) //mapped in the builder
                .ForMember(to => to.VariantParametrics, opts => opts.Ignore()) //mapped in the builder
                .ForMember(to => to.Parametrics, opts => opts.Ignore()) //mapped in the builder
                .ForMember(to => to.SelectedVariant, opts => opts.Ignore()); //not applicable?

        }

        public override string ProfileName
        {
            get { return GetType().Name; }
        }
    }
}
